package org.wheel.jpa.repository;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.wheel.base.dao.IBaseDao;
import org.wheel.jpa.utils.SpecificationUtils;

/**
 * @author klaus.wang
 */
@NoRepositoryBean
public interface BaseRepository<T, ID> extends IBaseDao<T>, JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

    @Override
    default void insert(T entity) {
        save(entity);
    }

    @Override
    default void update(T entity) {
        save(entity);
    }

    /**
     * getById
     *
     * @param id
     * @return
     */
    @Override
    default T getById(Serializable id) {

        @SuppressWarnings("unchecked")
        Optional<T> optional = findById((ID) id);

        return optional.isPresent() ? optional.get() : null;
    }

    /**
     * list
     *
     * @param parameter
     * @return
     */
    @Override
    default List<T> list(Object parameter) {
        return this.findAll(this.getSpecification(parameter));
    }

    /**
     * 构造查询条件
     *
     * @param parameter
     * @return
     */
    default Specification<T> getSpecification(Object parameter) {
        return SpecificationUtils.getPredicate(parameter);
    }

    /**
     * 默认排序
     * <p>
     * listNo 升序
     * createTime 降序
     *
     * @return
     */
    default Sort sort() {
        return Sort.by(Sort.Direction.ASC, "listNo").and(Sort.by(Sort.Direction.DESC, "createTime"));
    }

}
